package com.qd.system.service.person;

import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdqidi.dto.ApiResult;
import com.cdqidi.dto.ApiResultWrapper;
import com.cdqidi.excel.ExcelExport;
import com.cdqidi.excel.util.ExportPage;
import com.cdqidi.exception.ApiException;
import com.qd.common.sys.constant.Constants;
import com.qd.common.sys.constant.UserConstants;
import com.qd.common.sys.domain.entity.login.LoginUserDTO;
import com.qd.common.sys.domain.entity.login.LoginUserOrgDTO;
import com.qd.common.sys.domain.entity.org.OrgPersonDTO;
import com.qd.common.sys.domain.entity.org.OrgPersonsDTO;
import com.qd.common.sys.domain.entity.person.PersonDTO;
import com.qd.common.sys.domain.entity.person.PersonRoleDTO;
import com.qd.common.sys.domain.entity.person.PersonRolesDTO;
import com.qd.common.sys.domain.entity.role.RoleDTO;
import com.qd.common.sys.enums.BaseTableEnum;
import com.qd.common.sys.util.SecurityUtils;
import com.qd.system.config.AdminConfig;
import com.qd.system.dto.PasswordDto;
import com.qd.system.model.*;
import com.qd.system.service.dict.MbUtil;
import com.qd.system.service.login.LoginUserOrgService;
import com.qd.system.service.login.LoginUserService;
import com.qd.system.service.org.OrgPersonService;
import com.qd.system.service.org.OrgService;
import com.qd.system.service.role.RoleService;
import com.qd.system.util.FileConfirmUtil;
import com.qd.upload.constant.FileConfirmDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

import static java.util.stream.Collectors.toList;

/**
 * 人员操作辅助类
 *
 * @author sjk
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class PersonHoldService {
    private final OrgPersonService orgPersonService;
    private final PersonRoleService personRoleService;
    private final PersonService personService;
    private final OrgService orgService;
    private final LoginUserService loginUserService;
    private final LoginUserOrgService loginUserOrgService;
    private final RoleService roleService;
    private final AdminConfig adminConfig;
    private final HttpServletResponse response;
    private final AuthTokenService authTokenService;


    public OrgService getOrgService() {
        return orgService;
    }

    public PersonService getPersonService() {
        return personService;
    }

    public LoginUserService getLoginUserService() {
        return loginUserService;
    }

    public OrgPersonService getOrgPersonService() {
        return orgPersonService;
    }

    public LoginUserOrgService getLoginUserOrgService() {
        return loginUserOrgService;
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> savePerson(PersonDTO personDto) {
        String personId = personDto.getPersonId();
        if (!StringUtils.hasLength(personId)) {
            personId = IdWorker.getIdStr();
            personDto.setPersonId(personId);
        }
        checkMb(personDto);
        uploadAvatar(personDto);
        if (StringUtils.hasLength(personDto.getPassword())) {
            log.info("personId: {},password:{}", personId, personDto.getPassword());
            String password = new BCryptPasswordEncoder().encode(personDto.getPassword());
            personDto.setPassword(password);
        }
        personService.save(personDto);
        savePersonRole(personDto);
        saveOrgPersons(personDto);
        saveLoginUsers(personDto);
        return ApiResult.success(personDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> updatePerson(PersonDTO personDto) {
        if (Boolean.FALSE.equals(personService.isExistsById(personDto.getPersonId()))) {
            return ApiResult.error("用户信息不存在");
        }
        personDto.setPassword(null);
        checkMb(personDto);
        uploadAvatar(personDto);
        personService.update(personDto);
        savePersonRole(personDto);
        saveOrgPersons(personDto);
        saveLoginUsers(personDto);
        return ApiResult.success("更新成功");
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> resetPassword(PasswordDto passwordDto, boolean isCheckPersonExists) {
        if (isCheckPersonExists) {
            checkExists(passwordDto.getPersonId());
        }
        if (passwordDto.getPassword().length() < adminConfig.getPasswordLength()) {
            return ApiResult.error("密码长度不能小于" + adminConfig.getPasswordLength() + "位");
        }
        passwordDto.setPassword(SecurityUtils.encryptPassword(passwordDto.getPassword()));
        final LoginUserDTO loginUser = loginUserService.getByIdDto(passwordDto.getPersonId());
        if (null == loginUser) {
            return ApiResult.error("登录用户不存在");
        }
        if (Boolean.TRUE.equals(passwordDto.getIsLoginUser())) {
            //个人用户的话验证账户是否锁定，如果锁定不能修改密码
            if (loginUser.getState().equals(Constants.STATUS_DISABLE)) {
                return ApiResult.error("账户已经锁定，不能修改密码");
            }
        }
        if (Boolean.TRUE.equals(passwordDto.getIsCheckOldPassword())) {
            if (!SecurityUtils.matchesPassword(passwordDto.getOldPassword(), loginUser.getPassword())) {
                return ApiResult.error("原密码输入错误");
            }
        }
        loginUser.setPassword(passwordDto.getPassword());
        loginUser.setState(Constants.STATUS_ENABLE);
        loginUserService.update(loginUser);
        loginUser.freeData();
        passwordDto.freeData();
        return ApiResult.success("修改密码成功");
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByPersonId(String personId) {
        deletePerson(personId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByPersonIds(List<String> ids) {
        ids.forEach(this::deletePerson);
    }

    private void deletePerson(String personId) {
        checkExists(personId);
        loginUserService.checkLoginUser(personId);
        loginUserService.removeById(personId);
        personService.removeById(personId);

        final List<String> roleList = personRoleService.getPersonRoleById(personId);
        if (!roleList.isEmpty()) {
            personRoleService.removeBatchIds(roleList);
            roleList.clear();
        }

        final List<String> deptPersonList = orgPersonService.getOrgPersonByPersonId(personId);
        if (!deptPersonList.isEmpty()) {
            orgPersonService.removeBatchIds(deptPersonList);
            deptPersonList.clear();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> setRole(PersonRole personRole) {
        checkExists(personRole.getPersonId());
        roleService.checkRole(personRole.getRoleId());
        if (Boolean.TRUE.equals(personRoleService.isExists(personRole))) {
            return ApiResult.error("已经存在，请勿重复设置");
        }
        personRole.setAddTime(LocalDateTime.now());
        personRoleService.save(personRole);
        personRole.freeData();
        return ApiResult.success("设置成功");
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> setRoles(PersonRolesDTO personRolesDto) {
        final List<String> roles = personRolesDto.getRoles();
        final String personId = personRolesDto.getPersonId();
        checkExists(personId);
        if (!roles.isEmpty()) {
            roleService.checkIds(roles);
        }
        final List<String> oldRoleList = personRoleService.getPersonRoleById(personId);
        if (!oldRoleList.isEmpty()) {
            List<String> deleteList;
            if (roles.isEmpty()) {
                deleteList = oldRoleList;
            } else {
                deleteList = oldRoleList.stream().filter(roleId -> !roles.contains(roleId)).collect(toList());
            }
            if (!deleteList.isEmpty()) {
                personRoleService.removeBatchIds(deleteList);
            }
            oldRoleList.clear();
            deleteList.clear();
        }
        if (!roles.isEmpty()) {
            final List<PersonRole> pList = new ArrayList<>(roles.size());
            roles.forEach(roleId -> {
                final PersonRole personRole = new PersonRole();
                personRole.setPersonId(personId);
                personRole.setRoleId(roleId);
                if (Boolean.FALSE.equals(personRoleService.isExists(personRole))) {
                    personRole.setAddTime(LocalDateTime.now());
                    pList.add(personRole);
                }
                personRoleService.clearCache(personRole);
            });
            if (!pList.isEmpty()) {
                personRoleService.saveBatch(pList);
                pList.clear();
            }
        }
        return ApiResult.success("设置成功");
    }

    @Transactional(readOnly = true)
    public List<OrgPerson> buildOrgPersonList(OrgPersonsDTO orgPersonsDto) {
        String orgId = orgPersonsDto.getOrgId();
        List<String> personIds = orgPersonsDto.getPersonIds();
        orgService.checkId(orgId);
        personService.checkIds(personIds);
        List<OrgPerson> orgPersonList = new ArrayList<>(personIds.size());
        personIds.forEach(personId -> {
            OrgPerson orgPerson = orgPersonService.getUniqueByPersonIdAndOrgId(personId, orgId);
            if (null == orgPerson) {
                orgPerson = new OrgPerson();
                orgPerson.setOrgPersonId(IdWorker.getIdStr());
                orgPerson.setPersonId(personId);
                orgPerson.setOrgId(orgId);
                orgPerson.setAddTime(LocalDateTime.now());
                orgPersonList.add(orgPerson);
                orgPersonService.clearCache(orgPerson);
            }
        });
        return orgPersonList;
    }


    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> setOrg(List<OrgPerson> orgPersonList) {
        if (!orgPersonList.isEmpty()) {
            orgPersonService.saveBatch(orgPersonList);
            orgPersonList.clear();
        }
        return ApiResult.success("设置成功");
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> updateAvatar(String personId, String avatar) {
        final LoginUserDTO loginUser = loginUserService.getByIdDto(personId);
        if (loginUser == null) {
            return ApiResult.error("用户登录信息不存在");
        }
        final FileConfirmDTO fileConfirm = getFileConfirm(avatar);
        loginUser.setAvatar(fileConfirm.getOfficialFile());
        loginUserService.update(loginUser);
        loginUserService.buildDisplay(loginUser);
        Optional.ofNullable(personService.getByIdDto(personId)).ifPresent(p -> {
            p.setAvatar(fileConfirm.getOfficialFile());
            personService.update(p);
            p.freeData();
        });
        fileConfirm.freeData();
        authTokenService.updateTokenCache(loginUser);
        return ApiResult.success(loginUser);
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> updateLoginPerson(LoginUserDTO loginUserDto) {
        final LoginUserDTO loginUser = loginUserService.getByIdDto(loginUserDto.getPersonId());
        if (loginUser == null) {
            return ApiResult.error("用户登录信息不存在");
        }
        final String email = loginUserDto.getEmail();
        final String sex = loginUserDto.getSex();
        final String idCard = loginUserDto.getIdCard();
        final String mobile = loginUserDto.getMobile();
        final String personName = loginUserDto.getPersonName();

        boolean isUpdateField = false;
        boolean isUpdate = false;

        final Person updatePerson = new Person();
        updatePerson.setPersonId(loginUserDto.getPersonId());
        if (StringUtils.hasLength(personName)) {
            if (StringUtils.hasLength(loginUser.getPersonName())) {
                if (!loginUser.getPersonName().equals(personName)) {
                    isUpdateField = true;
                }
            } else {
                isUpdateField = true;
            }
            if (isUpdateField) {
                isUpdate = true;
                loginUser.setPersonName(personName);
                updatePerson.setPersonName(personName);
            }
        }
        if (StringUtils.hasLength(email)) {
            if (StringUtils.hasLength(loginUser.getEmail())) {
                if (!loginUser.getEmail().equals(email)) {
                    isUpdateField = true;
                }
            } else {
                isUpdateField = true;
            }
            if (isUpdateField) {
                isUpdate = true;
                loginUser.setEmail(email);
                updatePerson.setEmail(email);
            }
        }
        if (StringUtils.hasLength(sex)) {
            if (MbUtil.isNotExists(sex, BaseTableEnum.SEX)) {
                return ApiResult.error("性别输入错误");
            }
            isUpdateField = false;
            if (StringUtils.hasLength(loginUser.getSex())) {
                if (!loginUser.getSex().equals(sex)) {
                    isUpdateField = true;
                }
            } else {
                isUpdateField = true;
            }
            if (isUpdateField) {
                isUpdate = true;
                loginUser.setSex(sex);
                updatePerson.setSex(sex);
            }
        }
        if (StringUtils.hasLength(idCard)) {
            if (!IdcardUtil.isValidCard(idCard)) {
                return ApiResult.error("身份证不合法");
            }
            isUpdateField = false;
            if (StringUtils.hasLength(loginUser.getIdCard())) {
                if (!loginUser.getIdCard().equals(idCard)) {
                    isUpdateField = true;
                }
            } else {
                isUpdateField = true;
            }
            if (isUpdateField) {
                isUpdate = true;
                loginUser.setIdCard(idCard);
                updatePerson.setIdCard(idCard);
            }
        }
        if (StringUtils.hasLength(mobile)) {
            if (!PhoneUtil.isMobile(mobile)) {
                return ApiResult.error("请输入正确的手机号码");
            }
            isUpdateField = false;
            if (StringUtils.hasLength(loginUser.getMobile())) {
                if (!loginUser.getMobile().equals(mobile)) {
                    isUpdateField = true;
                }
            } else {
                isUpdateField = true;
            }
            if (isUpdateField) {
                isUpdate = true;
                loginUser.setMobile(mobile);
                updatePerson.setPhone(mobile);
            }
        }
        if (isUpdate) {
            final Person person = personService.getById(updatePerson.getPersonId());
            if (null != person) {
                personService.clearCache(person);
                personService.updateById(updatePerson);
                person.freeData();
                updatePerson.freeData();
            }
            loginUserService.update(loginUser);
            authTokenService.updateTokenCache(loginUser);
            loginUser.freeData();
        }
        loginUserDto.freeData();
        return ApiResult.success("更新成功");
    }

    private void checkMb(PersonDTO personDto) {
        if (MbUtil.isNotExists(personDto.getSex(), BaseTableEnum.SEX)) {
            throw new ApiException("性别值不存在");
        }
        if (!MbUtil.isExists(personDto.getUserStatus())) {
            throw new ApiException("用户状态值不存在");
        }
        final LoginUserDTO checkAccount = new LoginUserDTO();
        checkAccount.setAccount(personDto.getAccount());
        checkAccount.setPersonId(personDto.getPersonId());
        if (Boolean.TRUE.equals(loginUserService.checkAccountUnique(checkAccount))) {
            throw new ApiException("账号已经存在于登录信息表中");
        }
        if (StringUtils.hasLength(personDto.getIdCard())) {
            if (Boolean.TRUE.equals(checkIdCardUnique(personDto))) {
                throw new ApiException("身份证已经存在于人员信息表中");
            }
            final LoginUserDTO checkIdCard = new LoginUserDTO();
            checkIdCard.setIdCard(personDto.getIdCard());
            checkIdCard.setPersonId(personDto.getPersonId());
            if (loginUserService.checkIdCardUnique(checkIdCard)) {
                throw new ApiException("身份证已经存在于登录信息表中");
            }
        }
    }

    private void checkExists(String personId) {
        final Person person = personService.getById(personId);
        if (null == person) {
            throw new ApiException("用户信息不存在");
        }
    }


    private void saveOrgPersons(PersonDTO person) {
        final OrgPersonDTO orgPerson = new OrgPersonDTO();
        orgPerson.setPersonId(person.getPersonId());
        orgPerson.setOrgId(person.getOrgId());
        if (Boolean.FALSE.equals(orgPersonService.isExists(orgPerson))) {
            final OrgPerson deptPerson = buildOrgPerson(person);
            orgPersonService.save(deptPerson);
            deptPerson.freeData();
        }
        orgPerson.freeData();
    }

    private OrgPerson buildOrgPerson(PersonDTO person) {
        final OrgPerson orgPerson = new OrgPerson();
        orgPerson.setOrgId(person.getOrgId());
        if (null == person.getAddTime()) {
            orgPerson.setAddTime(person.getUpdateTime());
        } else {
            orgPerson.setAddTime(person.getAddTime());
        }
        orgPerson.setPersonId(person.getPersonId());
        return orgPerson;
    }

    private void savePersonRole(PersonDTO personDto) {
        final List<PersonRoleDTO> roleList = personDto.getPersonRoles();
        if (null == roleList || roleList.isEmpty()) {
            return;
        }
        roleList.forEach(personRoleDto -> {
            roleService.checkRole(personRoleDto.getRoleId());
            personRoleDto.setPersonId(personDto.getPersonId());
            if (Boolean.FALSE.equals(personRoleService.isExists(personRoleDto))) {
                if (null != personDto.getAddTime()) {
                    personRoleDto.setAddTime(personDto.getAddTime());
                }
                if (null != personDto.getUpdateTime()) {
                    personRoleDto.setAddTime(personDto.getUpdateTime());
                }
                personRoleService.save(personRoleDto);
                personRoleDto.freeData();
            }
        });
    }

    private Boolean checkAccountUnique(PersonDTO personDto) {
        boolean exists = false;
        final PersonDTO query = new PersonDTO();
        query.setAccount(personDto.getAccount());
        final Person person = personService.getOne(query);
        if (null != person) {
            if (StringUtils.hasLength(personDto.getPersonId())) {
                exists = !person.getPersonId().equals(personDto.getPersonId());
            } else {
                exists = true;
            }
            person.freeData();
        }
        query.freeData();
        return exists;
    }

    private Boolean checkIdCardUnique(PersonDTO personDto) {
        boolean exists = false;
        final PersonDTO query = new PersonDTO();
        query.setIdCard(personDto.getIdCard());
        final Person person = personService.getOne(query);
        if (null != person) {
            if (StringUtils.hasLength(personDto.getPersonId())) {
                exists = !person.getPersonId().equals(personDto.getPersonId());
            } else {
                exists = true;
            }
        }
        query.freeData();
        return exists;
    }

    private void saveLoginUsers(PersonDTO person) {
        final LoginUserDTO loginUser = buildLoginUserDto(person);
        final LoginUser loginUserInDb = loginUserService.getById(loginUser.getPersonId());
        if (null == loginUserInDb) {
            loginUserService.save(loginUser);
        } else {
            loginUserInDb.freeData();
            loginUser.setPassword(null);
            loginUserService.update(loginUser);
        }
        loginUser.freeData();
    }

    private LoginUserDTO buildLoginUserDto(PersonDTO person) {
        return loginUserService.modelToDto(buildLoginUser(person));
    }

    public LoginUser buildLoginUser(PersonDTO person) {
        final LoginUser loginUser = new LoginUser();
        loginUser.setOrgId(person.getOrgId())
                .setAccount(person.getAccount())
                .setPassword(person.getPassword())
                .setAvatar(person.getAvatar())
                .setEmail(person.getEmail())
                .setIdCard(person.getIdCard())
                .setMobile(person.getPhone())
                .setPersonId(person.getPersonId())
                .setPersonName(person.getPersonName())
                .setPassword(person.getPassword())
                .setSex(person.getSex());
        if (null == person.getUserStatus()) {
            loginUser.setState(Constants.STATUS_ENABLE);
        } else {
            loginUser.setState(person.getUserStatus());
        }
        return loginUser;
    }

    private FileConfirmDTO getFileConfirm(String avatar) {
        final FileConfirmDTO fileConfirm = FileConfirmUtil.singleFileConfirm(avatar, UserConstants.IMAGE);
        if (null == fileConfirm) {
            throw new ApiException("上传头像确认失败");
        }
        return fileConfirm;
    }

    private void uploadAvatar(PersonDTO personDto) {
        if (StringUtils.hasLength(personDto.getAvatar())) {
            final FileConfirmDTO confirmDto = getFileConfirm(personDto.getAvatar());
            personDto.setAvatar(confirmDto.getOfficialFile());
        }
    }


    /**
     * 获得个人信息
     *
     * @return 个人信息
     */
    public ApiResultWrapper<Object> getInfo() {
        final com.qd.common.sys.domain.login.LoginUser loginUser = SecurityUtils.getLoginUser();
        final String userId = loginUser.getUserId();
        final List<Map<String, String>> orgPersonList = orgPersonService.getListDtoByPersonId(userId);

        final Map<String, Object> map = new HashMap<>(3);
        map.put("loginUser", loginUser.getUser());
        map.put("orgList", orgPersonList);
        map.put("permissions", loginUser.getPermissions());
        return ApiResult.success(map);

    }

    /**
     * 导出Excel
     *
     * @param query 查询条件
     */
    @Transactional(readOnly = true)
    public void exportPersonRole(PersonRoleDTO query) {
        final ExportPage<PersonRole, PersonRoleDTO> exportPage = new ExportPage<>();
        final List<PersonRoleDTO> list = exportPage.getAllForPage(page -> personRoleService.page(page, query).getRecords());
        try {
            ExcelExport.downloadExcel(response, PersonRoleDTO.class, () -> list);
        } catch (IOException e) {
            log.error("导出失败", e);
            throw new ApiException("导出失败");
        }
    }

    /**
     * 导出Excel
     *
     * @param query 查询条件
     */
    @Transactional(readOnly = true)
    public void exportPerson(PersonDTO query) {
        final ExportPage<Person, PersonDTO> exportPage = new ExportPage<>();
        final List<PersonDTO> list = exportPage.getAllForPage(page -> personService.basePage(page, query, false).getRecords());
        try {
            ExcelExport.downloadExcel(response, PersonDTO.class, () -> list);
        } catch (IOException e) {
            log.error("导出失败", e);
            throw new ApiException("导出失败");
        }
    }

    /**
     * 导出Excel
     *
     * @param query 查询条件
     */
    @Transactional(readOnly = true)
    public void exportPersonOrg(OrgPersonDTO query) {
        final ExportPage<OrgPerson, OrgPersonDTO> exportPage = new ExportPage<>();
        final List<OrgPersonDTO> list = exportPage.getAllForPage(page -> orgPersonService.page(page, query).getRecords());
        try {
            ExcelExport.downloadExcel(response, OrgPersonDTO.class, () -> list);
        } catch (IOException e) {
            log.error("导出失败", e);
            throw new ApiException("导出失败");
        }
    }

    /**
     * 保存人员信息
     *
     * @param addPersonList    新增
     * @param updatePersonList 更新
     */
    public void savePersons(List<Person> addPersonList, List<Person> updatePersonList) {
        log.info("保存人员信息,add: " + addPersonList.size() + "，update: " + updatePersonList.size());
        if (!addPersonList.isEmpty()) {
            personService.saveBatch(addPersonList, ExportPage.DEFAULT_IMPORT_BATCH_SIZE);
        }
        if (!updatePersonList.isEmpty()) {
            personService.updateBatchById(updatePersonList, ExportPage.DEFAULT_IMPORT_BATCH_SIZE);
        }
    }

    /**
     * 保存机构和人员的关系
     *
     * @param orgPersonList 用户信息
     */
    public void saveOrgPersons(List<OrgPerson> orgPersonList) {
        log.info("保存机构和人员的关系,add: " + orgPersonList.size());
        if (orgPersonList.isEmpty()) {
            return;
        }
        orgPersonService.saveBatch(orgPersonList, ExportPage.DEFAULT_IMPORT_BATCH_SIZE);
    }


    /**
     * 保存登录用户
     *
     * @param addLoginUserList    添加
     * @param updateLoginUserList 更新
     */
    public void saveLoginUsers(List<LoginUser> addLoginUserList, List<LoginUser> updateLoginUserList) {
        log.info("保存人员信息,add: " + addLoginUserList.size() + "，update: " + updateLoginUserList.size());
        if (!addLoginUserList.isEmpty()) {
            loginUserService.saveBatch(addLoginUserList, ExportPage.DEFAULT_IMPORT_BATCH_SIZE);
        }
        if (!updateLoginUserList.isEmpty()) {
            loginUserService.updateBatchById(updateLoginUserList, ExportPage.DEFAULT_IMPORT_BATCH_SIZE);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> saveLoginUserOrg(LoginUserOrgDTO loginUserOrgDto) {
        if (Boolean.FALSE.equals(loginUserService.isExistsById(loginUserOrgDto.getPersonId()))) {
            return ApiResult.error("用户ID不存在[" + loginUserOrgDto.getPersonId() + "]");
        }
        if (Boolean.FALSE.equals(orgService.isExistsById(loginUserOrgDto.getOrgId()))) {
            return ApiResult.error("机构ID不存在[" + loginUserOrgDto.getOrgId() + "]");
        }
        OrgPerson orgPerson = orgPersonService.getUniqueByPersonIdAndOrgId(loginUserOrgDto.getPersonId(), loginUserOrgDto.getOrgId());
        if (null == orgPerson) {
            log.info("没有权限设置,orgId: " + loginUserOrgDto.getOrgId() + ",personId: " + loginUserOrgDto.getPersonId());
            return ApiResult.error("没有权限设置");
        }
        boolean remote = MbUtil.isNotExists(loginUserOrgDto.getRemote(), BaseTableEnum.LOGIN_REMOTE);
        if (remote) {
            return ApiResult.error("登录方式不存在[" + loginUserOrgDto.getRemote() + "]");
        }
        LoginUserOrg loginUserOrg = loginUserOrgService.getUniqueByPersonIdAndRemote(loginUserOrgDto.getPersonId(), loginUserOrgDto.getRemote());
        if (null == loginUserOrg) {
            loginUserOrgService.save(loginUserOrgDto);
        } else {
            if (!loginUserOrg.getOrgId().equals(loginUserOrgDto.getOrgId())) {
                loginUserOrgDto.setId(loginUserOrg.getId());
                loginUserOrgService.update(loginUserOrgDto);
            }
        }
        Optional.ofNullable(orgService.getById(loginUserOrgDto.getOrgId())).ifPresent(org -> buildCurrentOrg(SecurityUtils.getLoginUser(), org));
        return ApiResult.success("操作成功");
    }

    /**
     * 分页数据
     *
     * @param page 分页对象
     * @param dto  查询参数
     * @return 分页信息
     */
    @Transactional(readOnly = true)
    public IPage<PersonDTO> page(Page<Person> page, PersonDTO dto) {
        //不显示角色，角色在getById里面显示
//        final List<PersonDto> records = personDtoIPage.getRecords();
//        if (!records.isEmpty()) {
//            final List<String> personIds = records.stream().map(PersonDto::getPersonId).collect(toList());
//            final List<PersonRoleDto> list = personRoleService.getListByPersonIdsDto(personIds);
//            records.forEach(p -> {
//                if (!list.isEmpty()) {
//                    final List<PersonRoleDto> rList = list.stream().filter(pr -> p.getPersonId().equals(pr.getPersonId())).collect(toList());
//                    if (!rList.isEmpty()) {
//                        p.setPersonRoles(rList);
//                    }
//                }
//            });
//        }
        return personService.basePage(page, dto, false);
    }

    @Transactional(readOnly = true)
    public ApiResultWrapper<PersonDTO> getPersonAndRole(String personId) {
        final PersonDTO personDto = personService.getByIdDto(personId);
        if (null == personDto) {
            return ApiResult.error("人员信息不存在[" + personId + "]");
        }
        final List<RoleDTO> roleDtoList = personRoleService.getRoleByPersonId(personId);
        if (!roleDtoList.isEmpty()) {
            final List<PersonRoleDTO> rList = roleDtoList.stream().map(r -> {
                PersonRoleDTO role = new PersonRoleDTO();
                role.setRoleId(r.getRoleId());
                role.setRoleIdDisplay(r.getRoleName());
                return role;
            }).collect(toList());
            personDto.setPersonRoles(rList);
        }
        return ApiResult.success(personDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteOrgPerson(List<String> ids) {
        orgPersonService.checkIds(ids);
        ids.forEach(orgPersonService::removeById);
    }

    /**
     * 设置当前登录组织
     *
     * @param loginUser 登录信息
     * @param org       机构
     */
    private void buildCurrentOrg(com.qd.common.sys.domain.login.LoginUser loginUser, Org org) {
        loginUser.setCurrentOrgId(org.getOrgId());
        loginUser.getUser().setOrgId(org.getOrgId());
        loginUser.getUser().setOrgIdDisplay(org.getOrgName());
        authTokenService.refreshToken(loginUser);
    }
}